package com.example.chengzhong.service;

import cn.hutool.core.util.StrUtil;
import com.example.chengzhong.config.SerialPortListener;
import com.example.chengzhong.entity.CurrentWeight;
import com.example.chengzhong.entity.WeightRecord;
import com.example.chengzhong.mapperLianGui.CurrentWeightMapper;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PreDestroy;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedDeque;

@Service
public class SerialPortService {

    @Autowired
    private CurrentWeightMapper currentWeightMapper;
    private SerialPort serialPort;
    private InputStream inputStream;

    private StringBuilder sb = new StringBuilder();

    // 使用线程安全的队列存储最近30秒的记录
    private static final ConcurrentLinkedDeque<WeightRecord> recentRecords = new ConcurrentLinkedDeque<>();
    private String string = "";

    public void initPort(String portName, int baudRate,String id) throws Exception {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        serialPort = (SerialPort) portIdentifier.open("SpringBootSerial", 2000);
        serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
        inputStream = serialPort.getInputStream();
        // 注册事件监听
        serialPort.addEventListener(new SerialPortListener());
        serialPort.notifyOnDataAvailable(true);
        System.out.println("串口监听已启动: " + portName);

        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                try {
                    String replace = string.replace("wn", "").replace("kg", "").replace("\n", "").replace(" ", "").trim();
                    if (StrUtil.isBlank(replace)){
                        return;
                    }
                    Double weight = Math.round(Double.valueOf(replace)) - 2.0;
                    if (weight > 10) {
                        Date date = new Date();
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                        Integer seconds = 2;
                        // 清理过期记录（30秒前）
                        Instant now = Instant.now();
                        recentRecords.removeIf(record ->
                                Duration.between(record.getTimestamp(), now).getSeconds() > seconds);

                        // 检查是否与最近记录重复
                        boolean isDuplicate = recentRecords.stream()
                                .anyMatch(record ->
                                        Math.abs(record.getValue() - weight) < 0.001 && // 考虑浮点精度
                                                Duration.between(record.getTimestamp(), now).getSeconds() <= seconds);

                        if (!isDuplicate) {
                            CurrentWeight currentWeight = new CurrentWeight();
//                            currentWeight.setId("1925755778764468225"); //磅秤1
                            currentWeight.setId(id);  //磅秤2
                            currentWeight.setWeight(weight.intValue());
                            currentWeight.setRecordDate(date);
                            currentWeightMapper.updateById(currentWeight);

                            recentRecords.addFirst(new WeightRecord(weight.intValue()));

                            System.out.println("保存数据：" + sdf.format(date) + "  " + weight.intValue() + "kg");
                            return;
                        }

                        System.out.println("忽略数据：" + sdf.format(date) + "  " + weight.intValue() + "kg");

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 5000, 1000);
    }

    // 监听器内部类
    private class SerialPortListener implements SerialPortEventListener {
        @Override
        public void serialEvent(SerialPortEvent event) {
            if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
                try {
//                    byte[] buffer = new byte[1024];
//                    int len;
//                    while ((len = inputStream.read(buffer)) > 0) {
//                        String data = new String(buffer, 0, len);
//                        System.out.println("接收数据: " + data);
//                    }
                    byte[] buffer = new byte[1024 * 1024];
                    int len;
                    while ((len = inputStream.read(buffer)) > 0) {
                        String data = new String(buffer, 0, len);
                        sb.append(data.trim());
                        if (data.trim().endsWith("kg") ) {
//                            System.out.println("接收数据: " + sb);
                            string = sb.toString();
                            sb = new StringBuilder();
                        }
                        System.out.println("接收数据: " + data);
//                        if (data.contains("\n")){
//                            System.out.println("hahaha");
//                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 关闭串口（应用退出时调用）
    @PreDestroy
    public void closePort() {
        if (serialPort != null) {
            serialPort.removeEventListener();
            serialPort.close();
            System.out.println("串口资源已释放");
        }
    }
}
